using CfgTable;
using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using NetProtocol.Enum;
using NetProtocol.POD;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    public class LevelCharacterEntity : LevelPlayRealityEntity
    {
        public override uint MaxStore => 4;

        public DynLevelHeroEntity dynEntity { protected set; get; }

        public override float x => dynEntity.x;

        public override float y => dynEntity.y;

        public override float z => dynEntity.z;

        public override int dirEuler => dynEntity.dirEuler;

        public override bool active => true;

        private CfgPhysicalEntity _cfgEntity;
        public override CfgPhysicalEntity cfgEntity => _cfgEntity;
        /// <summary>
        /// 数据类
        /// </summary>
        public DynLevelHero dynLevelHero { private set; get; }
        public override string name => dynLevelHero.cfgHero.Name;
        public override int viewRange => 1000;
        public override int viewAngle => 360;
        /// <summary>
        /// 当前如果和NPC交互，交互的类型（英雄专属字段，代表当前npc交互类型，和base.base.interactType不同，interactType是实体专用字段，通常hero.InteractTypeWithEntity的值就来源于entity.interactType）
        /// </summary>
        public byte InteractTypeWithEntity { get; set; }
        /// <summary>
        /// 是否是我自己的英雄
        /// </summary>
        public bool isMine { get; private set; }

        public static LevelCharacterEntity CreateEntity(DynLevelHeroEntity dynEntity, DynLevelHero levelHero, bool isMine)
        {
            var entity = ClassPool<LevelCharacterEntity>.Get();

            entity.dynLevelHero = levelHero;
            entity.dynEntity = dynEntity;
            entity.RefreshEntityCfg();

            entity.isMine = isMine;

            entity.OnEntityCreate();

            return entity;
        }

        public void RefreshEntityCfg()
        {
            if (dynLevelHero.cfgHeroSkin.LevelEntity > 0)
            {
                var cfgEntity = TableCenter.physicalEntity.Get(dynLevelHero.cfgHeroSkin.LevelEntity);
                _cfgEntity = cfgEntity;
            }
            else
            {
                LogGame.LogWarning("LevelCharacterEntity CreateEntity cfgHeroSkin.Entity is 0");
            }
        }

        public override void EntityAddComponents()
        {
            var moveComponent = this.AddComponentWithPool<LevelMoveComponent>(ETComponentType.EntityMove);
            moveComponent.SetAsMainCharacter(isMine);

            this.AddComponentWithPool<EntityBindPointComponent>(ETComponentType.EntityBindPoint);
            this.AddComponentWithPool<EntityUIViewComponent>(ETComponentType.EntityUIView);
            this.AddComponentWithPool<LevelAnimationComponent>(ETComponentType.EntityAnimation);
            this.AddComponentWithPool<EntitySmallPetComponent>(ETComponentType.SmallPetComponent);
            this.AddComponentWithPool<LevelBuffDisplayComponent>(ETComponentType.EntityBuffDisplay);
        }

        public override LevelBuffHolder GetBuffHolder()
        {
            return dynLevelHero.buffHolder;
        }


        protected override string GetEntityLoadPath()
        {
            if (_cfgEntity == null)
            {
                return string.Empty;
            }

            return PathConstant.GetCharacterLevelPrefabPath(_cfgEntity.EntityAsset);
        }

        public override void OnEntityBirth()
        {
            // 出生不在设置位置，由逻辑层

            //bool result = LevelPlayManager.Instance.levelPlay.navigationCtrl.FindNearestPoint(transform.position, out var realEndPos);
            //if (!result)
            //{
            //    LogGame.LogError($"Level Entity can't find NearestPoint,entityId:{id} pos:{transform.position.ToString()}");
            //    return;
            //}
            //this.transform.position = realEndPos;
        }

        /// <summary>
        /// 数据坐标（非transform.position）转换成Unity矢量
        /// </summary>
        /// <returns></returns>
        public override Vector3 GetUnityVec3Pos()
        {
            return GameMathUtil.LogicPos2UnityPos(dynEntity.x, dynEntity.y, dynEntity.z);
        }

        /// <summary>
        /// 数据坐标（非transform.position）转换成Unity矢量
        /// </summary>
        /// <returns></returns>
        public override Vector2 GetUnityVec2Pos()
        {
            return new Vector2(dynEntity.x, dynEntity.z);
        }

        public override BaseDynLevelEntity GetDynEntityData()
        {
            return dynEntity;
        }

        public override void SyncEntityPos(float x, float y, float z, float speedRatio, EntityMoveDirType dirType, LevelMoveReason reason)
        {
            dynEntity.UpdatePos(x, y, z);
            var targetPositon = LevelPlayUtil.GetAdjustedPosByGround(dynEntity.x, dynEntity.y, dynEntity.z);
            if (reason == LevelMoveReason.Move || reason == LevelMoveReason.TakeElevator)
            {
                this.GetMoveComponent().SetSmoothMoveTarget(targetPositon, speedRatio, dirType);
            }
            else //移动失败/跳跃失败/传送，都直接传送
            {
                this.GetMoveComponent().TransferLocation(targetPositon);
            }
        }

        /// <summary>
        /// 客户端根据角色当前显示的位置更新数据的位置
        /// </summary>
        /// <param name="position"></param>
        public override void UpdatePosToData(Vector3 position)
        {
            Vector3 logicPos = GameMathUtil.UnityPos2LogicPos(position);
            dynEntity.UpdatePos(logicPos.x, logicPos.y, logicPos.z);
        }

        public async UniTaskVoid ChangeHero(LevelHeroPOD leaderHeroPOD)
        {
            var holder = this.transform.parent;
            TryHideEntity();
            dynLevelHero.InitByPOD(leaderHeroPOD);
            RefreshEntityCfg();
            await LoadAndInstantiate(holder);
            LevelPlayModule.Instance.levelPlay.regionCtrl?.cameraCtrl?.CharacterFllowLook(transform, transform);
        }

        /// <summary>
        /// 立即停止移动动画
        /// </summary>
        public void StopMoveAnimImmediately()
        {
            this.GetMoveComponent().StopMove(true);
        }

        #region 属性

        public override int GetDefaultSpeed()
        {
            return cfgEntity.DefaultSpeed;
        }

        #endregion

        public override void OnReset()
        {
            base.OnReset();
            dynEntity = null;
            _cfgEntity = null;
            dynLevelHero = null;
            InteractTypeWithEntity = 0;
            isMine = false;
        }
    }
}
